In [2]:
import param
import numpy as np
import holoviews as hv
from holoviews.streams import Selection1D
hv.extension('bokeh')
import pickle
import pandas as pd
import datetime
import matplotlib.pyplot as plt

%matplotlib inline



In [3]:
from IPython.core.display import display, HTML
display(HTML("<style>"
    + "#notebook { padding-top:0px !important; } " 
    + ".container { width:100% !important; } "
    + ".end_space { min-height:0px !important; } "
    + "</style>"))



In [4]:
data = pd.read_csv('../data/processed/report_trails.csv')
#data.set_index(['facility', 'status', 'date', 'analysis', 'type'], inplace=True)

In [5]:
analysis = '2017-01-01'

data_final = data[data.analysis == analysis]
data_final.set_index(['facility'], inplace= True)

In [6]:
def compute_ltfu_rate(data, date):
    n_suivi = data[(data.type == 'longitudinal') & (data.date == date)]['values'].sum()
    ltfu = data[(data.type == 'longitudinal') &
                (data.date == date) &
                (data.status == 'Followed')]['values'].sum()
    ltfu_rate = ltfu / n_suivi
    return ltfu_rate

def get_expected_ltfu(data, ltfu_rate, date):
    out = ltfu_rate * data[(data.type == 'longitudinal') & 
                  (data.date == date)]['values'].sum()
    return out

def make_z_scores(data, ltfu_rate, date):
    z_score = (data[(data.type == 'longitudinal') & 
                  (data.date == date) & 
                  (data.status == 'Followed')]['values'].sum() - expected) / expected
    return z_score

def make_limits(expected):
    max_expected = int(max(expected))
    range_expected = pd.Series(list(range(0, max_expected)))
    z_down = 1 - 1.96*np.sqrt(1 / range_expected)
    z_up = 1 + 1.96*np.sqrt(1 / range_expected)
    return (range_expected, z_down, z_up)
    

dates = ['2007-01-01','2008-01-01','2009-01-01','2010-01-01','2011-01-01','2012-01-01','2013-01-01','2014-01-01',
        '2015-01-01','2016-01-01','2017-01-01']

date = dates[8]
ltfu_rate = compute_ltfu_rate(data_final, date)
expected_facility = data_final.groupby('facility').apply(get_expected_ltfu , ltfu_rate, date)
expected = get_expected_ltfu(data , ltfu_rate, date)
z_score = make_z_scores(data_final, ltfu_rate, date)

range_expected, z_down, z_up = make_limits(expected_facility)

rate_ratio = ltfu_rate /data_final.groupby('facility').apply(compute_ltfu_rate, date)

In [7]:
rr_df = 's'
for date_f in dates :
    ltfu_rate_f = compute_ltfu_rate(data_final, date_f)
    rate_ratio_f = pd.DataFrame(ltfu_rate_f /data_final.groupby('facility').apply(compute_ltfu_rate, date_f))
    rate_ratio_f['date'] = date_f
    if type(rr_df) is pd.core.frame.DataFrame:
        rr_df = rr_df.append(rate_ratio_f)
    if type(rr_df) is str:
        rr_df = rate_ratio_f
rr_df.columns = ['rate_ratio', 'date']
rr_df = rr_df.reset_index()

In [8]:
rr_df['rate_ratio'] = np.log(rr_df['rate_ratio'])
dataset = hv.Dataset(rr_df, vdims=[('rate_ratio')])
heatmap = hv.HeatMap(dataset.aggregate(['date', 'facility'], np.mean), label='LTFU Evolution')

In [9]:
a = pd.DataFrame(expected_facility)
u = a.merge(pd.DataFrame(rate_ratio), left_index = True , right_index = True)
u.columns = ['Expected Followed', 'Risk Ratio']
u = u.reset_index()

In [10]:
dict_spec = {'Curve.limits':{'style':dict(color='red', line_width=1.5)}, 
             'Curve.patients_curve': {'style':dict(color='black')}}



funnel_plot = hv.Points(u, kdims = ['Expected Followed', 'Risk Ratio'], vdims=['facility'])
limits_up = hv.Curve((range_expected , z_down), group='limits', extents=(None, -1,None,4))
limits_down = hv.Curve((range_expected , z_up), group='limits', extents=(None, -1,None,4))

stream = Selection1D(source=funnel_plot)

# Define function to compute curve based on tap location
dat_transv = data[(data.analysis == analysis) & (data.date <= date) & (data.type == 'transversal')]

def tap_facility(index, dat_transv=dat_transv):
    if index == [] :
        index = 0
    if type(index) is list :
        index = index[0]
    index = list(expected_facility.index)[index]
    dat = dat_transv[dat_transv.facility == index]
    dat = dat[(dat.type == 'transversal') &
               (dat.status == 'Followed')]
    dat.loc[:,'date'] = dat.loc[:, 'date'].astype('datetime64[ns]')
    dat = dat.sort_values(['date'])
    return hv.Curve(dat, 'date', 'values', group = 'patients_curve')

In [11]:
%opts Points [width=410 height=500 fontsize={'xticks': '6pt'} , tools=['tap','hover']] (size=8 alpha=.5)
%opts Curve [width=410 height=500 yaxis='right', tools=['hover']](color=Cycle(values=['indianred'])){+framewise}
%opts HeatMap [width=410 height=500 logz=True fontsize={'xticks': '6pt'}, tools=['hover'] xrotation=90] (cmap='RdBu_r') 

limits_up*limits_down*funnel_plot + hv.DynamicMap(tap_facility, kdims=[], streams=[stream]) + heatmap


/anaconda3/lib/python3.6/site-packages/bokeh/core/json_encoder.py:80: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  elif np.issubdtype(type(obj), np.float):
Out[11]:
  • add national fgraph as default
  • do prediction
  • spider graph for retention categories
  • map for the Z scores
  • Selection multiple facilities
  • Add vline progression
  • Add all categories

http://holoviews.org/gallery/apps/bokeh/nytaxi_hover.html

http://holoviews.org/user_guide/Custom_Interactivity.html


In [ ]: